// http.ts
import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type AxiosError } from "axios";
import { ElLoading } from "element-plus";
import { nextTick } from "vue";
// 存储所有活跃请求的Map
const pendingRequests = new Map();
let loadingCount = 0;
let loadingInstance: ReturnType<typeof ElLoading.service> | null = null;
type HttpMethod = "get" | "post" | "put" | "delete" | "patch";
const service: AxiosInstance = axios.create({
	baseURL: "/api",
	timeout: 5000
});

export interface customRequestConfig extends AxiosRequestConfig {
	showLoading?: boolean;
}

export interface customAxiosResponse extends AxiosResponse {
	showLoading?: boolean;
}
function getRequestKey(config: customRequestConfig) {
	return [config.method, config.url, JSON.stringify(config.params), JSON.stringify(config.data)].join("&");
}

/**
 * 添加请求到pendingRequests
 * @param {*} config
 */
function addPendingRequest(config: customRequestConfig) {
	const requestKey = getRequestKey(config);
	config.cancelToken =
		config.cancelToken ||
		new axios.CancelToken(cancel => {
			if (!pendingRequests.has(requestKey)) {
				pendingRequests.set(requestKey, cancel);
			}
		});
}

/**
 * 移除请求
 * @param {*} config
 */
function removePendingRequest(config: customRequestConfig) {
	const requestKey = getRequestKey(config);
	if (pendingRequests.has(requestKey)) {
		const cancel = pendingRequests.get(requestKey);
		cancel(requestKey);
		pendingRequests.delete(requestKey);
	}
}

const showLoading = () => {
	if (loadingCount === 0) {
		nextTick(() => {
			loadingInstance = ElLoading.service({
				fullscreen: true,
				lock: true,
				text: "Loading",
				background: "rgba(0, 0, 0, 0.7)"
			});
		});
	}
	loadingCount++;
};

const hideLoading = () => {
	loadingCount--;
	if (loadingCount <= 0) {
		loadingInstance?.close();
		loadingCount = 0;
		loadingInstance = null;
	}
};

service.interceptors.request.use(
	(config: customRequestConfig) => {
		config.headers = config.headers || {};
		removePendingRequest(config);
		addPendingRequest(config);
		if (config.showLoading) {
			showLoading();
		}
		// 可在此添加类型安全的header处理
		return config;
	},
	(error: AxiosError) => {
		if (error.config?.showLoading) {
			hideLoading();
		}
		return Promise.reject(error);
	}
);

service.interceptors.response.use(
	<T = any>(res: AxiosResponse<T>) => {
		if (res.config.showLoading) {
			hideLoading();
		}
		removePendingRequest(res.config); // 请求完成，移除记录
		return res.data;
	},
	(error: AxiosError) => {
		if (axios.isCancel(error)) {
			console.log("已取消的重复请求：", error.message);
			return Promise.reject({
				isCancel: true,
				message: "请求被取消"
			});
		}
		removePendingRequest(error.config || {}); // 请求失败，移除记录
		if (error.config?.showLoading) {
			hideLoading();
		}
		return Promise.reject(error);
	}
);

export function commonFetch<T = any>(method: HttpMethod, url: string, data?: any, options?: customRequestConfig): Promise<T> {
	if (method === "get") {
		return service[method](url, {
			params: data,
			...options
		});
	}
	return service[method](url, data, options);
}

export function requestGet<T = any>(url: string, data?: Record<string, any>, options?: customRequestConfig): Promise<T> {
	return commonFetch("get", url, data, options);
}

export function requestPost<T = any>(url: string, data?: any, options?: customRequestConfig): Promise<T> {
	return commonFetch("post", url, data, options);
}

export default service;
